home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / Var_Dump.php < prev   
Encoding:
PHP Script  |  2006-04-07  |  19.1 KB  |  511 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available through the world-wide-web at the following url:           |
  11. // | http://www.php.net/license/3_0.txt.                                  |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Frederic Poeydomenge <fpoeydomenge at free dot fr>          |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id$
  20.  
  21. require_once 'Var_Dump/Renderer.php';
  22.  
  23. /**
  24.  * Wrapper for the var_dump function.
  25.  *
  26.  * " The var_dump function displays structured information about expressions
  27.  * that includes its type and value. Arrays are explored recursively
  28.  * with values indented to show structure. "
  29.  *
  30.  * The Var_Dump class captures the output of the var_dump function,
  31.  * by using output control functions, and then uses external renderer
  32.  * classes for displaying the result in various graphical ways :
  33.  * simple text, HTML/XHTML text, HTML/XHTML table, XML, ...
  34.  *
  35.  * @package Var_Dump
  36.  * @category PHP
  37.  * @author Frederic Poeydomenge <fpoeydomenge at free dot fr>
  38.  */
  39.  
  40. define ('VAR_DUMP_START_GROUP',          1);
  41. define ('VAR_DUMP_FINISH_GROUP',         2);
  42. define ('VAR_DUMP_START_ELEMENT_NUM',    3);
  43. define ('VAR_DUMP_START_ELEMENT_STR',    4);
  44. define ('VAR_DUMP_FINISH_ELEMENT',       5);
  45. define ('VAR_DUMP_FINISH_STRING',        6);
  46.  
  47. define ('VAR_DUMP_TYPE_ARRAY',           1);
  48. define ('VAR_DUMP_TYPE_OBJECT',          2);
  49.  
  50. define ('VAR_DUMP_PREG_MATCH',           0);
  51. define ('VAR_DUMP_PREG_SPACES',          1);
  52. define ('VAR_DUMP_PREG_KEY_QUOTE',       2);
  53. define ('VAR_DUMP_PREG_KEY',             3);
  54. define ('VAR_DUMP_PREG_STRING_TYPE',     4);
  55. define ('VAR_DUMP_PREG_STRING_LENGTH',   5);
  56. define ('VAR_DUMP_PREG_STRING_VALUE',    6);
  57. define ('VAR_DUMP_PREG_VALUE',           7);
  58. define ('VAR_DUMP_PREG_VALUE_REFERENCE', 8);
  59. define ('VAR_DUMP_PREG_VALUE_TYPE',      9);
  60. define ('VAR_DUMP_PREG_VALUE_COMPL',    10);
  61. define ('VAR_DUMP_PREG_VALUE_RESOURCE', 11);
  62. define ('VAR_DUMP_PREG_ARRAY_END',      12);
  63. define ('VAR_DUMP_PREG_ARRAY_START',    13);
  64. define ('VAR_DUMP_PREG_ARRAY_TYPE',     14);
  65. define ('VAR_DUMP_PREG_ARRAY_COUNT',    15);
  66. define ('VAR_DUMP_PREG_STRING_COMPL',   16);
  67.  
  68. class Var_Dump
  69. {
  70.  
  71.     /**
  72.      * Default configuration options.
  73.      *
  74.      * @var array
  75.      * @access public
  76.      */
  77.     var $defaultOptions = array(
  78.         'display_mode' => 'XHTML_Text', // Display mode.
  79.         'ignore_list'  => NULL          // List of ignored class names.
  80.     );
  81.  
  82.     /**
  83.      * Run-time configuration options.
  84.      *
  85.      * @var array
  86.      * @access public
  87.      */
  88.     var $options = array();
  89.  
  90.     /**
  91.      * Rendering object.
  92.      *
  93.      * @var object
  94.      * @access public
  95.      */
  96.     var $renderer = NULL;
  97.  
  98.     /**
  99.      * Rendering configuration options.
  100.      *
  101.      * See Var_Dump/Renderer/*.php for the complete list of options
  102.      *
  103.      * @var array
  104.      * @access public
  105.      */
  106.     var $rendererOptions = array();
  107.  
  108.     /**
  109.      * Class constructor.
  110.      *
  111.      * The factory approach must be used in relationship with the
  112.      * toString() method.
  113.      * See Var_Dump/Renderer/*.php for the complete list of options
  114.      *
  115.      * @see Var_Dump::toString()
  116.      * @param mixed $options String (display mode) or array (Global parameters).
  117.      * @param array $rendererOptions Parameters for the rendering.
  118.      * @access public
  119.      */
  120.     function Var_Dump($options = array(), $rendererOptions = array())
  121.     {
  122.  
  123.         if (! is_null($options)) {
  124.             if (is_string($options)) {
  125.                 $options = array(
  126.                     'display_mode' => $options
  127.                 );
  128.             }
  129.             $this->options = array_merge (
  130.                 $this->defaultOptions,
  131.                 $options
  132.             );
  133.         }
  134.  
  135.         if (! is_null($rendererOptions) and is_array($rendererOptions)) {
  136.             $this->rendererOptions = $rendererOptions;
  137.             $this->renderer = & Var_Dump_Renderer::factory(
  138.                 $this->options['display_mode'],
  139.                 $this->rendererOptions
  140.             );
  141.         }
  142.  
  143.     }
  144.  
  145.     /**
  146.      * Attempt to return a concrete Var_Dump instance.
  147.      *
  148.      * The factory approach must be used in relationship with the
  149.      * toString() method.
  150.      * See Var_Dump/Renderer/*.php for the complete list of options
  151.      *
  152.      * @see Var_Dump::toString()
  153.      * @param mixed $options String (display mode) or array (Global parameters).
  154.      * @param array $rendererOptions Parameters for the rendering.
  155.      * @access public
  156.      */
  157.     function & factory($options = array(), $rendererOptions = array())
  158.     {
  159.         $obj = new Var_Dump($options, $rendererOptions);
  160.         return $obj;
  161.     }
  162.  
  163.     /**
  164.      * Uses a renderer object to return the string representation of a variable.
  165.      *
  166.      * @param mixed $expression The variable to parse.
  167.      * @return string The string representation of the variable.
  168.      * @access public
  169.      */
  170.     function toString($expression)
  171.     {
  172.  
  173.         if (is_null($this->renderer)) {
  174.             return '';
  175.         }
  176.  
  177.         $family = array(); // element family
  178.         $depth  = array(); // element depth
  179.         $type   = array(); // element type
  180.         $value  = array(); // element value
  181.  
  182.         // When xdebug is loaded, disable the custom fancy var_dump() function,
  183.         // that is not compatible with the regexp parsing below, by forcing
  184.         // the "html_errors" configuration option to "off"
  185.  
  186.         if (extension_loaded('xdebug')) {
  187.             ini_set('html_errors', '0');
  188.         }
  189.  
  190.         // Captures the output of the var_dump function,
  191.         // by using output control functions.
  192.  
  193.         ob_start();
  194.         var_dump($expression);
  195.         $variable = ob_get_contents();
  196.         ob_end_clean();
  197.  
  198.         // When xdebug is loaded, restore the value of the
  199.         // "html_errors" configuration option
  200.  
  201.         if (extension_loaded('xdebug')) {
  202.             ini_restore('html_errors');
  203.         }
  204.  
  205.         // Regexp that parses the output of the var_dump function.
  206.         // The numbers between square brackets [] are the reference
  207.         // of the captured subpattern, and correspond to the entries
  208.         // in the resulting $matches array.
  209.  
  210.         preg_match_all(
  211.             '!^
  212.               (\s*)                                 # 2 spaces for each depth level
  213.               (?:                                   #
  214.                 (?:\[("?)(.*?)\\2\]=>)              # Key [2-3]
  215.                   |                                 #   or
  216.                 (?:(&?string\((\d+)\))\s+"(.*))     # String [4-6]
  217.                   |                                 #   or
  218.                 (                                   # Value [7-11]
  219.                   (&?)                              #   - reference [8]
  220.                   (bool|int|float|resource|         #   - type [9]
  221.                   NULL|\*RECURSION\*|UNKNOWN:0)     #
  222.                   (?:\((.*?)\))?                    #   - complement [10]
  223.                   (?:\sof\stype\s\((.*?)\))?        #   - resource [11]
  224.                 )                                   #
  225.                   |                                 #   or
  226.                 (})                                 # End of array/object [12]
  227.                   |                                 #   or
  228.                 (?:(&?(array|object)\((.+)\).*)\ {) # Start of array/object [13-15]
  229.                   |                                 #   or
  230.                 (.*)                                # String (additional lines) [16]
  231.               )                                     #
  232.             $!Smx',
  233.             $variable,
  234.             $matches,
  235.             PREG_SET_ORDER
  236.         );
  237.  
  238.         // Used to keep the maxLen of the keys for each nested variable.
  239.  
  240.         $stackLen = array();
  241.         $keyLen = array();
  242.         $maxLen = 0;
  243.  
  244.         // Used when matching a string, to count the remaining
  245.         // number of chars before the end of the string.
  246.  
  247.         $countdown = 0;
  248.  
  249.         // Loop through the matches of the previously defined regexp.
  250.  
  251.         reset($matches);
  252.         while (list($key, $match) = each($matches)) {
  253.  
  254.             $count = count($match) - 1;
  255.  
  256.             // Find which alternative has been matched in the regexp,
  257.             // by looking at the number of elements in the $match array.
  258.  
  259.             switch ($count) {
  260.  
  261.                 // Key
  262.                 //=====
  263.                 // - Compute the maxLen of the keys at the actual depth
  264.  
  265.                 case VAR_DUMP_PREG_KEY:
  266.                     $len = strlen($match[VAR_DUMP_PREG_KEY]);
  267.                     if ($len > $maxLen) {
  268.                         $maxLen = $len;
  269.                     }
  270.                     if (empty($match[VAR_DUMP_PREG_KEY_QUOTE])) {
  271.                         $family[] = VAR_DUMP_START_ELEMENT_NUM;
  272.                     } else {
  273.                         $family[] = VAR_DUMP_START_ELEMENT_STR;
  274.                     }
  275.                     $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
  276.                     $type[]  = NULL;
  277.                     $value[] = $match[VAR_DUMP_PREG_KEY];
  278.                     break;
  279.  
  280.                 // String
  281.                 //========
  282.                 // - Set the countdown (remaining number of chars before eol) =
  283.                 //   len of the string - matched len + 1 (final ")
  284.  
  285.                 case VAR_DUMP_PREG_STRING_TYPE:
  286.                 case VAR_DUMP_PREG_STRING_LENGTH:
  287.                 case VAR_DUMP_PREG_STRING_VALUE:
  288.                     $countdown =
  289.                         $match[VAR_DUMP_PREG_STRING_LENGTH]
  290.                         - strlen($match[VAR_DUMP_PREG_STRING_VALUE])
  291.                         + 1;
  292.                     $family[] = VAR_DUMP_FINISH_STRING;
  293.                     $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
  294.                     $type[] = $match[VAR_DUMP_PREG_STRING_TYPE];
  295.                     if ($countdown == 0) {
  296.                         $value[] = substr($match[VAR_DUMP_PREG_STRING_VALUE], 0, -1);
  297.                     } else {
  298.                         $value[] = $match[VAR_DUMP_PREG_STRING_VALUE];
  299.                     }
  300.                     break;
  301.  
  302.                 // String (additional lines)
  303.                 //===========================
  304.                 // - Compute new countdown value
  305.                 // - Pop value off the end of the array, and concatenate new value
  306.                 // - Last additional line : remove trailing "
  307.                 // - Push new value onto the end of array
  308.  
  309.                 case VAR_DUMP_PREG_STRING_COMPL:
  310.                     if ($countdown > 0) {
  311.                         $countdown -= strlen($match[VAR_DUMP_PREG_MATCH]) + 1;
  312.                         $new_value =
  313.                             array_pop($value) . "\n" .
  314.                             $match[VAR_DUMP_PREG_STRING_COMPL];
  315.                         if ($countdown == 0) {
  316.                             $new_value = substr($new_value, 0, -1);
  317.                         }
  318.                         array_push($value, $new_value);
  319.                     }
  320.                     break;
  321.  
  322.                 // Value
  323.                 //=======
  324.  
  325.                 case VAR_DUMP_PREG_VALUE:
  326.                 case VAR_DUMP_PREG_VALUE_REFERENCE:
  327.                 case VAR_DUMP_PREG_VALUE_TYPE:
  328.                 case VAR_DUMP_PREG_VALUE_COMPL:
  329.                 case VAR_DUMP_PREG_VALUE_RESOURCE:
  330.                     $family[] = VAR_DUMP_FINISH_ELEMENT;
  331.                     $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
  332.                     switch ($match[VAR_DUMP_PREG_VALUE_TYPE]) {
  333.                         case 'bool':
  334.                         case 'int':
  335.                         case 'float':
  336.                             $type[] =
  337.                                 $match[VAR_DUMP_PREG_VALUE_REFERENCE] .
  338.                                 $match[VAR_DUMP_PREG_VALUE_TYPE];
  339.                             $value[] = $match[VAR_DUMP_PREG_VALUE_COMPL];
  340.                             break;
  341.                         case 'resource':
  342.                             $type[] =
  343.                                 $match[VAR_DUMP_PREG_VALUE_REFERENCE] .
  344.                                 $match[VAR_DUMP_PREG_VALUE_TYPE] .
  345.                                 '(' . $match[VAR_DUMP_PREG_VALUE_RESOURCE] . ')';
  346.                             $value[] = $match[VAR_DUMP_PREG_VALUE_COMPL];
  347.                             break;
  348.                         default:
  349.                             $type[] =
  350.                                 $match[VAR_DUMP_PREG_VALUE_REFERENCE] .
  351.                                 $match[VAR_DUMP_PREG_VALUE_TYPE];
  352.                             $value[] = NULL;
  353.                             break;
  354.                     }
  355.                     break;
  356.  
  357.                 // End of array/object
  358.                 //=====================
  359.                 // - Pop the maxLen of the keys off the end of the stack
  360.                 // - If the last element on the stack is an array(0) or object(0),
  361.                 //   replace it by a standard element
  362.  
  363.                 case VAR_DUMP_PREG_ARRAY_END:
  364.                     $oldLen = array_pop($stackLen);
  365.                     $keyLen[$oldLen[0]] = $maxLen;
  366.                     $maxLen = $oldLen[1];
  367.                     if (
  368.                         ($family[count($family) - 1] == VAR_DUMP_START_GROUP)
  369.                             and
  370.                         ($type[count($type) - 1] === 0)
  371.                     ) {
  372.                         $family[count($family) - 1] = VAR_DUMP_FINISH_ELEMENT;
  373.                         $type[count($type) - 1] = $value[count($value) - 1];
  374.                         $value[count($value) - 1] = NULL;
  375.                     } else {
  376.                         $family[] = VAR_DUMP_FINISH_GROUP;
  377.                         $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
  378.                         $type[] = NULL;
  379.                         $value[] = $match[VAR_DUMP_PREG_ARRAY_END];
  380.                                         }
  381.                     break;
  382.  
  383.                 // Start of array/object
  384.                 //=======================
  385.                 // - If object is in the "ignore_list", jump at the end of it
  386.                 // - Else process it normally :
  387.                 //   - Push the maxLen of the keys onto the end of the stack
  388.                 //   - Initialize new maxLen to 0
  389.  
  390.                 case VAR_DUMP_PREG_ARRAY_START:
  391.                 case VAR_DUMP_PREG_ARRAY_TYPE:
  392.                 case VAR_DUMP_PREG_ARRAY_COUNT:
  393.                     
  394.                     $parse = TRUE;
  395.  
  396.                     // If object is in the "ignore_list", jump at the end of it.
  397.  
  398.                     if ($match[VAR_DUMP_PREG_ARRAY_TYPE] == 'object') {
  399.                         $infos = $match[VAR_DUMP_PREG_ARRAY_COUNT];
  400.                         $class_name = substr($infos, 0, strpos($infos, ')'));
  401.                         if (
  402.                             ! is_null($this->options['ignore_list'])
  403.                                 and
  404.                             in_array($class_name, $this->options['ignore_list'])
  405.                         ) {
  406.                             $family[] = VAR_DUMP_FINISH_STRING;
  407.                             $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
  408.                             $type[] = 'object(' . $class_name . ')';
  409.                             $value[] = 'Not parsed.';
  410.                             while ($parse) {
  411.                                 list($dummy, $each) = each($matches);
  412.                                 if (
  413.                                     $match[VAR_DUMP_PREG_SPACES] == $each[VAR_DUMP_PREG_SPACES]
  414.                                         and
  415.                                     (count($each) - 1) == VAR_DUMP_PREG_ARRAY_END
  416.                                 ) {
  417.                                     $parse = FALSE;
  418.                                 }
  419.                             };
  420.                         }
  421.                     }
  422.  
  423.                     // If not, process it normally.
  424.  
  425.                     if ($parse) {
  426.  
  427.                         array_push($stackLen, array(count($family), $maxLen));
  428.                         $maxLen = 0;
  429.                         $family[] = VAR_DUMP_START_GROUP;
  430.                         $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
  431.                         $type[] = (int) $match[VAR_DUMP_PREG_ARRAY_COUNT];
  432.                         $value[] = $match[VAR_DUMP_PREG_ARRAY_START];
  433.  
  434.                     }
  435.  
  436.                     break;
  437.  
  438.             }
  439.  
  440.         }
  441.  
  442.         $this->renderer->initialize($family, $depth, $type, $value, $keyLen);
  443.  
  444.         return $this->renderer->toString();
  445.  
  446.     }
  447.  
  448.     /**
  449.      * Attempt to return a concrete singleton Var_Dump instance.
  450.      *
  451.      * The singleton approach must be used in relationship with the
  452.      * displayInit() and display() methods.
  453.      * See Var_Dump/Renderer/*.php for the complete list of options
  454.      *
  455.      * @see Var_Dump::display(), Var_Dump::displayInit()
  456.      * @return object Var_Dump instance
  457.      * @access public
  458.      */
  459.     function & singleton()
  460.     {
  461.         static $instance;
  462.         if (! isset($instance)) {
  463.             $instance = new Var_Dump(array(), array(), array());
  464.         }
  465.         return $instance;
  466.     }
  467.  
  468.     /**
  469.      * Initialise the singleton object used by the display() method.
  470.      *
  471.      * @see Var_Dump::singleton(), Var_Dump::display()
  472.      * @param mixed $options String (display mode) or array (Global parameters).
  473.      * @param array $rendererOptions Parameters for the rendering.
  474.      * @access public
  475.      */
  476.     function displayInit($options = array(), $rendererOptions = array())
  477.     {
  478.         $displayInit = & Var_Dump::singleton();
  479.         $displayInit->Var_Dump($options, $rendererOptions);
  480.     }
  481.  
  482.     /**
  483.      * Outputs or returns a string representation of a variable.
  484.      *
  485.      * @see Var_Dump::singleton(), Var_Dump::displayInit()
  486.      * @param mixed $expression The variable to parse.
  487.      * @param bool $return Whether the variable should be echoed or returned.
  488.      * @param mixed $options String (display mode) or array (Global parameters).
  489.      * @param array $rendererOptions Parameters for the rendering.
  490.      * @return string If returned, the string representation of the variable.
  491.      * @access public
  492.      */
  493.     function display($expression, $return = FALSE, $options = NULL, $rendererOptions = NULL)
  494.     {
  495.         $display = & Var_Dump::singleton();
  496.         if (! is_null($options) or ! is_null($rendererOptions)) {
  497.             if (is_null($rendererOptions)) {
  498.                 $rendererOptions = array();
  499.             }
  500.             $display->Var_Dump($options, $rendererOptions);
  501.         }
  502.         if ($return === TRUE) {
  503.             return $display->toString($expression);
  504.         } else {
  505.             echo $display->toString($expression);
  506.         }
  507.     }
  508.  
  509. }
  510.  
  511. ?>